using System;
using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Text;
using System.Xml;
using System.Globalization;
using IWCommunity.Common;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;

namespace IWCommunity.Blogs.WebControls
{
    /// <summary>
    /// Could use the categorieslist control instead of this one and it might be quicker..need to test
    /// Also there is no maximunm number of tags...all tags will show in this web part. Which is okay for single blog.
    /// </summary>
    public class TagCloud : List
    {
        private int totalCount = 0;
        private int minCount = 1;
        private int maxCount = 1;
        private string tagCssPrefix = String.Empty;
        private string tagColumnName = "Tags";
        private string fullTagPageUrl = string.Empty;
        private string tagPageURL = "Lists/Categories/Category.aspx?Name="; //TODO:add site URL
        private char delimiter = ';';

        [Bindable(true)]
        [Category("Tagging Setting")]
        [DefaultValue(";")]
        [Localizable(true)]
        public char Delimiter
        {
            get
            {
                return this.delimiter;
            }
            set
            {
                this.delimiter = value;
            }
        }

        [Bindable(true)]
        [Category("Tagging Setting")]
        [DefaultValue("")]
        [Localizable(true)]
        [Description("The URL that's redirected to by clicking on a tag")]
        public string TagPageURL
        {
            get
            {
                return ((this.tagPageURL == null) ? String.Empty : this.tagPageURL);
            }

            set
            {
                this.tagPageURL = value;
            }
        }

        [Bindable(true)]
        [Category("Tagging Setting")]
        [DefaultValue("")]
        [Localizable(true)]
        public string TagColumnName
        {
            get
            {
                return ((this.tagColumnName == null) ? String.Empty : this.tagColumnName);
            }

            set
            {
                this.tagColumnName = value;
            }
        }


        protected override System.Xml.XmlDocument BuildDocument()
        {
            try
            {

                ArrayList arrayTags = this.GetTags();
                XmlDocument oDoc = new XmlDocument();
                oDoc.LoadXml("<rows/>"); //add outer element called rows

              
                foreach (Tag tag in arrayTags)
                {

                    XmlElement rowNode = oDoc.CreateElement("row"); //add inner element called row
                    rowNode.SetAttribute("tagUrl", tag.Url); //add appropriate attrributes
                    rowNode.SetAttribute("title", tag.Count.ToString() + " posts");
                    rowNode.SetAttribute("displayTitle", SPEncode.HtmlEncode(tag.Name));
                    rowNode.SetAttribute("weight", GetTagWeight(tag.Count, this.maxCount));
                    oDoc.DocumentElement.AppendChild(rowNode);
                }

                return oDoc;
                
            }
            catch (Exception ex)
            {
                Logger.LogError(ex); //log error
                XmlDocument oError = new XmlDocument();
                oError.LoadXml(string.Format("<Error>{0}</Error>", ex.Message));
                return oError;
            }
        }

        protected override void OnLoad(EventArgs e)
        {
            if (System.Web.HttpContext.Current.Request.UserAgent.ToLower().Contains("robot"))
                this.Visible = false;
            
            base.OnLoad(e);
        }


      

        private ArrayList GetTags()
        {
            Hashtable ht = new Hashtable();
            ArrayList al = new ArrayList();
            TextInfo ti = CultureInfo.CurrentCulture.TextInfo;

            SPWeb Web = SPContext.Current.Web;

            //get list (which is probably the Posts list)
            SPList list = Web.Lists[ListName];

            //TODO:change HT to use sorted list so that arraylist is not required
                if (list.Fields.ContainsField(this.tagColumnName))
                {
                    SPListItemCollection items = list.Items;

                    foreach (SPListItem item in items)
                    {

                        string[] itemtags = item.GetFormattedValue(this.tagColumnName).Trim().Split(this.delimiter);
                        int tagsCount = itemtags.Length;
                        for (int i = 0; i < tagsCount; i++)
                        {
                            string itemtag = itemtags[i].Trim();

                            itemtag = ti.ToTitleCase(itemtag);

                            if (!String.IsNullOrEmpty(itemtag))
                            {
                                if (ht.ContainsKey(itemtag))
                                {
                                    int index = (int)ht[itemtag];
                                    // update the count for the tag
                                    ((Tag)al[index]).Count++;
                                    // update the min/max count;
                                    int currcount = ((Tag)al[index]).Count;
                                    if (maxCount < currcount)
                                    {
                                        maxCount = currcount;
                                    }
                                    else if (minCount > currcount)
                                    {
                                        minCount = currcount;
                                    }

                                }
                                else
                                {
                                    al.Add(new Tag(itemtag, 1, GetFullTagPageURL(this.tagPageURL) + SPEncode.HtmlEncode(itemtag)));
                                    ht.Add((string)itemtag, al.Count - 1);
                                }
                                totalCount++;
                            }

                        }


                    }
              

            }

            al.Sort();
            return al;

        }

        /// <summary>
        /// Combine the current web URL and the tags page URL to get fully qualified URL for tag links
        /// </summary>
        /// <param name="relativeTagPage"></param>
        /// <returns></returns>
        private string GetFullTagPageURL(string relativeTagPage)
        {
            if (fullTagPageUrl.Length > 0)
                return fullTagPageUrl;

            string webUrl = SPContext.Current.Web.Url;
            fullTagPageUrl = SPUrlUtility.CombineUrl(webUrl, relativeTagPage);
            return fullTagPageUrl;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="Count"></param>
        /// <param name="MaxCount"></param>
        /// <returns></returns>
        private string GetTagWeight(int Count, int MaxCount)
        {
            double Percent = (double)((Count * 100) / MaxCount);

            if (Percent > 90)
            {
                return "1";
            }
            else if (Percent > 70)
            {
                return "2";
            }
            else if (Percent > 50)
            {
                return "3";
            }
            else if (Percent > 30)
            {
                return "4";
            }
            else if (Percent > 10)
            {
                return "5";
            }
            else
            {
                return "6";
            }
        }
    }
}
